#pragma once

///////////////////////////////////////////////////////////////

#define COUNT_OF(C_ARRAY) (sizeof(C_ARRAY) / sizeof( (C_ARRAY)[0] ))

///////////////////////////////////////////////////////////////

struct DeleteFunc
{
	template <class _TypeClass>
	void operator() (_TypeClass* ptr)
	{
		if (ptr) delete ptr;
	}
};
/*
struct IncRefFunc
{
	template <class _TypeClass>
	void operator() (_TypeClass* ptr)
	{
		SAFE_INC_REF(ptr);
	}
};

struct DecRefFunc
{
	template <class _TypeClass>
	void operator() (_TypeClass* ptr)
	{
		SAFE_DEC_REF(ptr);
	}
};*/

///////////////////////////////////////////////////////////////

template <class Operation>
struct Pair1stFunc
{
	Pair1stFunc(const Operation& op) : m_Op(op) { }
	template <class Pair> void operator () (Pair& p) { m_Op(p.first); }
	Operation m_Op;
};

template <class Operation>
inline Pair1stFunc<Operation> pair1st(const Operation& op)
{
	return Pair1stFunc<Operation>(op);
}

///////////////////////////////////////////////////////////////

template <class Operation>
struct Pair2ndFunc
{
	Pair2ndFunc(const Operation& op) : m_Op(op) { }
	template <class Pair> void operator () (Pair& p) { m_Op(p.second); }
	Operation m_Op;
};

template <class Operation>
inline Pair2ndFunc<Operation> pair2nd(const Operation& op)
{
	return Pair2ndFunc<Operation>(op);
}

///////////////////////////////////////////////////////////////

template <class Operation>
struct PairBothFunc
{
	PairBothFunc(const Operation& op) : m_Op(op) { }
	template <class Pair> void operator () (Pair& p) { m_Op(p.first); m_Op(p.second); }
	Operation m_Op;
};

template <class Operation>
inline PairBothFunc<Operation> pair_both(const Operation& op)
{
	return PairBothFunc<Operation>(op);
}

///////////////////////////////////////////////////////////////

template <class Container, class Fn>
inline void SafeIterate(Container t, Fn fn)
{
	if (t.empty()) return;
	
	Container::value_type* valArray = StackAlloc(Container::value_type, sizeof(Container::value_type) * t.size());
	uint count = 0;
	for (Container::iterator itr = t.begin(), end = t.end(); itr != end; ++itr)
	{
		memcpy(&valArray[count++], &*itr, sizeof(Container::value_type));
	}

	ASSERT(count == t.size());

	for (uint i=0; i<count; ++i)
	{
		fn(valArray[i]);
	}

	StackFree(valArray);
}

///////////////////////////////////////////////////////////////

